class ReconnectWebSocket {
    constructor(options) {
      // 默认配置
      const defaultOptions = {
        url: 'wss://echo.websocket.org',
        pingInterval: 30000,      // 心跳间隔30秒
        pongTimeout: 10000,       // Pong超时10秒
        reconnectInterval: 5000,  // 重连间隔5秒
        maxRetries: Infinity,     // 最大重连次数
        autoConnect: true,        // 自动连接
        onOpen: null,             // 连接成功回调
        onMessage: null,          // 收到消息回调
        onClose: null,            // 连接关闭回调
        onError: null             // 错误回调
      };
  
      this.config = { ...defaultOptions, ...options };
      this.ws = null;
      this.reconnectAttempts = 0;
      this.isDestroyed = false;
      this.pingTimeout = null;
      this.reconnectTimer = null;
      this.heartbeatTimer = null;
  
      if (this.config.autoConnect) {
        this.connect();
      }
    }
  
    connect() {
      if (this.isDestroyed) return;
  
      this.ws = new WebSocket(this.config.url);
  
      this.ws.addEventListener('open', (event) => this.handleOpen(event));
      this.ws.addEventListener('message', (event) => this.handleMessage(event));
      this.ws.addEventListener('close', (event) => this.handleClose(event));
      this.ws.addEventListener('error', (event) => this.handleError(event));
    }
  
    handleOpen(event) {
      console.log('WebSocket connected');
      this.reconnectAttempts = 0;
      this.config.onOpen?.(event);
      this.startHeartbeat();
    }
  
    handleMessage(event) {
      // 收到Pong消息重置心跳检测
      if (event.data === 'pong') {
        this.resetHeartbeat();
        return;
      }
      this.config.onMessage?.(event);
    }
  
    handleClose(event) {
      console.log('WebSocket closed:', event.code, event.reason);
      this.clearTimers();
      this.config.onClose?.(event);
  
      // 非正常关闭且未达到最大重试次数
      if (event.code !== 1000 && 
          this.reconnectAttempts < this.config.maxRetries) {
        this.scheduleReconnect();
      }
    }
  
    handleError(event) {
      console.error('WebSocket error:', event);
      this.config.onError?.(event);
      this.ws.close(); // 触发close事件进行重连
    }
  
    startHeartbeat() {
      this.heartbeatTimer = setInterval(() => {
        this.send('ping');
        this.pingTimeout = setTimeout(() => {
          console.warn('Pong timeout, closing connection...');
          this.ws.close();
        }, this.config.pongTimeout);
      }, this.config.pingInterval);
    }
  
    resetHeartbeat() {
      clearTimeout(this.pingTimeout);
    }
  
    scheduleReconnect() {
      if (this.isDestroyed) return;
  
      const delay = this.config.reconnectInterval * Math.pow(2, this.reconnectAttempts);
      this.reconnectAttempts++;
  
      console.log(`Reconnecting in ${delay}ms, attempt ${this.reconnectAttempts}`);
      
      this.reconnectTimer = setTimeout(() => {
        this.connect();
      }, Math.min(delay, 30000)); // 最大间隔不超过30秒
    }
  
    send(data) {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send(data);
      }
    }
  
    close(code = 1000, reason) {
      this.isDestroyed = true;
      this.clearTimers();
      this.ws?.close(code, reason);
    }
  
    clearTimers() {
      clearInterval(this.heartbeatTimer);
      clearTimeout(this.pingTimeout);
      clearTimeout(this.reconnectTimer);
    }
  }
  
  // 使用示例
  const ws = new ReconnectWebSocket({
    url: 'wss://your-websocket-endpoint',
    onOpen: (event) => {
      console.log('Connected to server');
      ws.send(JSON.stringify({ type: 'auth', token: 'your_token' }));
    },
    onMessage: (event) => {
      console.log('Received message:', event.data);
    },
    onClose: (event) => {
      console.log('Connection closed');
    },
    onError: (event) => {
      console.error('WebSocket error:', event);
    }
  });
  
  // 手动关闭连接
  // ws.close();